using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MeetFuture.MRC
{
	public partial class clsRackList
	{
        private const string key_RackSplit = "_";
        private const string key_split = ",";
        private Dictionary<string, clsRackInfo> _RackList = new Dictionary<string, clsRackInfo>();

        public clsRackList()
        {
            this._RackList = new Dictionary<string, clsRackInfo>();
        }       
        public Dictionary<string, clsRackInfo> RackList
        {
            get { return this._RackList; }
        }
        public void Add(clsRackInfo rack)
        {
            try
            {
                clsRackInfo tmpRack = null;
                this._RackList.TryGetValue(rack.Name, out tmpRack);
                if (tmpRack == null)
                {
                    this._RackList.Add(rack.Name, rack);
                } 
                else
                {
                    this._RackList[rack.Name] = rack;
                }
            }
            catch (System.Exception ex)
            {	
            }            
        }
        public clsRackInfo FindRackByRackID(string RackID)
        {
            clsRackInfo result = null;
            try
            {
                this._RackList.TryGetValue(RackID, out result);
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }
        public clsRackInfo FindRackByRackID(string RackId, clsRackPosition.RackPositionType PosType)
        {
            clsRackInfo result = null;
            try
            {
                string rackid = RackId.IndexOf(key_RackSplit) >= 0 ? RackId.Substring(0, RackId.IndexOf(key_RackSplit)) : RackId;
                string rackPosId = Convert.ToInt32(RackId.Substring(RackId.IndexOf(key_RackSplit) + 1, RackId.Length - RackId.IndexOf(key_RackSplit) - 1)).ToString();
                clsRackInfo rack = null;
                this._RackList.TryGetValue(rackid, out rack);
                if (rack != null)
                {
                    clsRackPosition rackPos = rack.FindclsPositionByPositonID(rackPosId);
                    if (rackPos.PositionType == PosType)
                    {
                        result = rack;
                    }           
                }                      
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }
        public clsRackPosition FindRackPositionByLot(string LotId)
        {
            clsRackPosition result = null;
            try
            {
                foreach (clsRackInfo rack in this._RackList.Values)
                {
                    result = rack.FindclsPositionByLot(LotId);
                    if (result != null)
                    {
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }
        public clsRackPosition FindRackPositionByLot(string LotId, clsRackPosition.RackPositionType PosType)
        {
            clsRackPosition result = null;
            try
            {
            	foreach (clsRackInfo rack in this._RackList.Values)
            	{
                    result = rack.FindclsPositionByLot(LotId, PosType);
                    if (result != null)
                    {
                        break;
                    }
            	}
            }
            catch (System.Exception ex)
            {	
            }
            return result;
        }
        public List<clsRackPosition> FindEmptyPositions(int Empty_Number, clsRackPosition.RackPositionType PosType)
        {
            List<clsRackPosition> result = new List<clsRackPosition>();
            try
            {
                int index = 0;
                foreach (clsRackInfo rack in this._RackList.Values)
                {
                    rack.UpdateInfo();

                    var availablePositions = rack.RackPositions.Where(o => o.Value.PositionType == PosType && string.IsNullOrWhiteSpace(o.Value.LotID)).Select(o => new { Column = (Convert.ToInt16(o.Value.PositionID) % rack.RackWidth) + 1, RackPosition = o.Value }).ToList();
                    var groupedPositions = availablePositions.GroupBy(o => o.Column).Select(o => new { Column = o.Key, EmptyPositions = o.Select(p => p.RackPosition).ToList()}).Where(o => o.EmptyPositions.Count() >= 2).ToDictionary(o => o.Column, o => o.EmptyPositions);

                    if (groupedPositions.Count > 0)
                    {
                        foreach (var group in groupedPositions.Values)
                        {
                            foreach (var rackPos in group)
                            {
                                if (string.IsNullOrWhiteSpace(rackPos.LotID))
                                {
                                    result.Add(rackPos);
                                    index++;
                                }
                                if (index >= Empty_Number)
                                {
                                    return result;
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (clsRackPosition rackPos in rack.RackPositions.Values)
                        {
                            if (rackPos.PositionType == PosType)
                            {
                                if (string.IsNullOrWhiteSpace(rackPos.LotID))
                                {
                                    result.Add(rackPos);
                                    index++;
                                }
                                if (index >= Empty_Number)
                                {
                                    return result;
                                }
                            }
                        }
                    }
                }
                result = null;
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }
        public List<clsLotInfo> GetLotList(clsRackPosition.RackPositionType PosType)
        {
            List<clsLotInfo> result = new List<clsLotInfo>();
            try
            {
                foreach (clsRackInfo rack in this._RackList.Values)
                {
                    rack.UpdateInfo();
                    foreach (clsRackPosition rackPos in rack.RackPositions.Values)
                    {
                        if (!rackPos.IsError)
                        {
                            if (rackPos.PositionType == PosType)
                            {
                                if (!string.IsNullOrWhiteSpace(rackPos.LotID))
                                {
                                    clsLotInfo lotinfo = new clsLotInfo(rackPos.LotID);
                                    lotinfo.Status = LotStatus.Lot_OnRack;
                                    lotinfo.RackID = rackPos.RackName;
                                    lotinfo.RackPosition = rackPos;
                                    result.Add(lotinfo);
                                }
                            }
                        }                        
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }
        public void UpdateInfo()
        {
            try
            {
            	foreach (clsRackInfo rack in this._RackList.Values)
            	{
                    rack.UpdateInfo();
            	}
            }
            catch (System.Exception ex)
            {	
            }
        }
        public string ToObjectString(clsRackPosition.RackPositionType PosType)
        {
            string result = string.Empty;
            try
            {
                result += "[";
                foreach (clsRackInfo rack in this._RackList.Values)
                {
                    result += rack.ToObjectString(PosType);
                }
                result += "]";
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }
	}
}
